//导入express框架
var express = require("express");
var formidable = require("formidable");
//解决跨域问题
const cors = require("cors");
let connection = require("./mysql");
const path = require("path");
const fs = require("fs");
// 中间件 获取参数的
const bodyParser = require("body-parser");
const multer = require("multer");

const upload = multer({ dest: "uploads/" });

var app = express();
connection.connect();

app.use(cors());
app.use(bodyParser.json({ limit: "21000000kb" }));
app.use(bodyParser.urlencoded({ extended: false }));
app.use("/static", express.static("static"));
app.use("/uploads", express.static("uploads"));

//获取json数据
// app.use((req, res, next) => {
//   res.header("Access-Control-Allow-Origin", "*");
//   res.header("Access-Control-Allow-Headers", "X-Requested-With");
//   res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OP0TIONS");
//   // res.header("Content-Type", "application/json;charset=utf-8");
//   return next();
// });

function responseCallBack(res, data) {
  res.status(200);
  res.json(data);
}

app.get("/", function (req, res) {
  responseCallBack(res, "hello world");
});

app.post("/test", function (req, res) {
  responseCallBack(res, {
    name: "七夕节快乐",
  });
});

app.post("/upload", upload.single("file"), function (req, res) {
  // req.file 是 `avatar` 文件的信息
  // req.body 将具有文本域数据，如果存在的话
  const newName = `uploads/${Date.now()}.png`;
  fs.rename(req.file.path, newName, (err) => {
    if (err) res.json({ code: -1 });
    res.json({ url: newName });
  });
});

// 新增商品
app.post("/addgoods", async function (req, res) {
  let tokenRes = await validToken(req);
  if (tokenRes == true) {
    let name = req.body.name;
    let desc = req.body.desc;
    let price = req.body.price;
    let url = req.body.url;
    let count = req.body.count;
    let results = await ControlAPI_obj_async({
      sql: `INSERT INTO product(id,name,description,price,image,count) VALUES(0,?,?,?,?,?)`,
      value: [name, desc, price, url, count],
    });
    if (results.message == "" || !results.message) {
      responseCallBack(res, {
        code: 0,
        data: null,
        msg: "",
      });
    } else {
      responseCallBack(res, {
        code: 2,
        data: null,
        msg: results.message,
      });
    }
  } else {
    responseCallBack(res, tokenRes);
  }
});

// 更新商品状态
app.post("/updategoodsstatus", async function (req, res) {
  let tokenRes = await validToken(req);
  if (tokenRes == true) {
    let id = res.body.id;
    let valid = res.body.valid;
    let results = await ControlAPI_obj_async({
      sql: `UPDATE product SET isValid = ? where id = '${id}'`,
      value: [valid],
    });
    responseCallBack(res, {
      code: 0,
      data: null,
      msg: "",
    });
  } else {
    responseCallBack(res, tokenRes);
  }
});

// 更新商品
app.post("/updategoods", async function (req, res) {
  let tokenRes = await validToken(req);
  if (tokenRes == true) {
    let id = req.body.id;
    let name = req.body.name;
    let desc = req.body.desc;
    let price = req.body.price;
    let url = req.body.url;
    let count = req.body.count;
    let results = await ControlAPI_obj_async({
      sql: `UPDATE product SET name = ?,description = ?, price = ?, image = ?, count = ? where id = '${id}'`,
      value: [name, desc, price, url, count],
    });
    responseCallBack(res, {
      code: 0,
      data: null,
      msg: "",
    });
  } else {
    responseCallBack(res, tokenRes);
  }
});

// 获取全部商品列表
app.post("/getallgoods", async function (req, res) {
  let page = req.body.pageNum;
  let size = req.body.pageSize;
  let totalRes = await ControlAPI_obj_async({
    sql: `SELECT count(*) as count from product`,
  });
  let totalCount = JSON.parse(JSON.stringify(totalRes))[0].count;
  let results = await ControlAPI_obj_async({
    sql: `SELECT * FROM product limit ${(page - 1) * size},${size}`,
  });
  if (results.message == "" || !results.message) {
    responseCallBack(res, {
      code: 0,
      data: {
        list: results,
        totalSize: totalCount,
      },
      msg: "",
    });
  } else {
    responseCallBack(res, {
      code: 2,
      data: null,
      msg: results.message,
    });
  }
});

// 获取商品列表
app.post("/getgoods", async function (req, res) {
  let page = req.body.pageNum;
  let size = req.body.pageSize;
  let totalRes = await ControlAPI_obj_async({
    sql: `SELECT count(*) as count from product`,
  });
  let totalCount = JSON.parse(JSON.stringify(totalRes))[0].count;
  let results = await ControlAPI_obj_async({
    sql: `SELECT * FROM product where isValid = 1 and count > 0 limit ${
      (page - 1) * size
    },${size}`,
  });
  if (results.message == "" || !results.message) {
    responseCallBack(res, {
      code: 0,
      data: {
        list: results,
        totalSize: totalCount,
      },
      msg: "",
    });
  } else {
    responseCallBack(res, {
      code: 2,
      data: null,
      msg: results.message,
    });
  }
});

// 登录
app.post("/login", async function (req, res) {
  let userName = req.body.userName;
  let password = req.body.password;
  let results = await ControlAPI_obj_async({
    sql: `SELECT * FROM admin where account = '${userName}'`,
  });
  if (results.length >= 1) {
    let item = results[0];
    if (item.account == userName && item.password == password) {
      // 登录成功 生成token
      let token = create_token(32);
      await updateUserToken(userName, token);
      responseCallBack(res, {
        code: 0,
        data: {
          token: token,
        },
        msg: "",
      });
    } else {
      // 密码或者账号错误
      responseCallBack(res, {
        code: 2,
        data: null,
        msg: "密码或者账号错误",
      });
    }
  } else {
    responseCallBack(res, {
      code: 2,
      data: null,
      msg: "该账号不存在",
    });
  }
});

// 登出
app.post("/logout", async function (req, res) {
  let tokenRes = await validToken(req);
  let tokenPass = req.get("token");
  if (tokenRes == true) {
    connection.query(
      `UPDATE admin SET token = ? WHERE token = '${tokenPass}'`,
      [""],
      function (error, results, fields) {
        res.json({
          msg: "logout成功",
          code: -1,
          data: null,
        });
      }
    );
  } else {
    res.json(tokenRes);
  }
});

// 校验token有效性 true token有效  json为无效
async function validToken(req) {
  let tokenPass = req.get("token");
  let results = await ControlAPI_obj_async({
    sql: `SELECT * FROM admin where token = '${tokenPass}'`,
    value: null,
  });
  if (results.length >= 1) {
    let item = results[0];
    if (tokenPass == item.token) {
      return true;
    }
  } else {
    return {
      msg: "token已过期，请重新登录",
      code: -1,
      data: null,
    };
  }
}

// 单查询 异步改为同步
function ControlAPI_obj_async(data) {
  return new Promise((resolved, rejected) => {
    dataBaseControl(data["sql"], data["value"], (result) => {
      if (result === null) {
        rejected(null);
      } else {
        resolved(result);
      }
    });
  });
}

// 多条查询 异步改为同步 全部结束后回调
function ControlAPI_objs_async(...vars) {
  let len = vars.length;
  let promiseList = [];
  for (let i = 0; i < len; i++) {
    let sqlObj = vars[i];
    promiseList.push(
      new Promise((resolved, rejected) => {
        dataBaseControl(sqlObj["sql"], sqlObj["value"], (result) => {
          if (result === null) {
            rejected(null);
          } else {
            resolved(result);
          }
        });
      })
    );
  }
  return Promise.all(promiseList);
}

// 更新用户token
async function updateUserToken(userName, token) {
  let data = {
    sql: `UPDATE admin SET token = ? where account = '${userName}'`,
    value: [token],
  };
  let result = await ControlAPI_obj_async(data);
}

// 创建token
function create_token(leng) {
  leng = leng == undefined ? 32 : leng; //如果没设置token长度自动为32位
  //预设随机字符串
  let chars = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz23456789";
  let token = "";
  //以长度单位进行循环
  for (let i = 0; i < leng; ++i) {
    token += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return token; ///返回之前使用md5加密一下
}

// 查询sql方法
function dataBaseControl(sql, args, callback) {
  if (args == null || args.length == 0) {
    connection.query(sql, function (error, results, fields) {
      if (error) {
        console.error(error);
        callback(null);
        return;
      }
      callback(results);
    });
  } else {
    connection.query(sql, args, function (error, results, fields) {
      if (error) {
        console.error(error);
        callback(null);
        return;
      }
      callback(results);
    });
  }
}

// 开启端口
var server = app.listen(3001, "0.0.0.0", function () {
  var host = server.address().address;
  var port = server.address().port;
  console.log("服务器启动成功了端口是", port);
});
